﻿using Microsoft.Xna.Framework;
using System;

namespace Innovator
{
	public class Camera : Component, I3DComponent
	{
		//internal values
		Vector3 position = Vector3.Zero;
		Matrix rotationMatrix = Matrix.Identity;
		Vector3 target = new Vector3(0, 0, -1);
		Vector3 up = Vector3.Up;
		Matrix view;
		Matrix projection;
		public virtual Vector3 Target
		{
			get { return target; }
			set { target = value; }
		}
		public virtual Vector3 Up
		{
			get { return up; }
			set { up = value; }
		}
		public virtual Matrix View
		{
			get { return view; }
			set { view = value; }
		}
		public virtual Matrix Projection
		{
			get { return projection; }
			set { projection = value; }
		}
		//public I3Dcomponent values
		public virtual Vector3 Position { get { return position; } set { position = value; } }
		public virtual Vector3 Scale { get { return Vector3.One; } set { } }
		public Vector3 EulerRotation
		{
			get { return MathUtil.MatrixToVector3(Rotation); }
			set { Rotation = MathUtil.Vector3ToMatrix(value); }
		}
		public virtual Matrix Rotation { get { return rotationMatrix; } set { rotationMatrix = value; } }
		public virtual BoundingBox BoundingBox
		{
			get { return new BoundingBox(Position - Vector3.One, Position + Vector3.One); }
		}
		//constructor
		public Camera(GameScreen Parent) : base(Parent) { }
		public Camera() : base() { }
		//update camera
		public override void Update()
		{
			Vector3 newForward = Target - Position;
			newForward.Normalize();

			Matrix rotationMatrixCopy = this.Rotation;
			rotationMatrixCopy.Forward = newForward;

			Vector3 referenceVector = Vector3.Up;
			if (rotationMatrixCopy.Forward.Y == referenceVector.Y ||
				rotationMatrixCopy.Forward.Y == -referenceVector.Y)
				referenceVector = Vector3.Backward;
			rotationMatrixCopy.Right = Vector3.Cross(this.Rotation.Forward, referenceVector);
			rotationMatrixCopy.Up = Vector3.Cross(this.Rotation.Right, this.Rotation.Forward);

			this.Rotation = rotationMatrixCopy;
			Up = Rotation.Up;
			View = Matrix.CreateLookAt(Position, Target, Up);
			Projection = MathUtil.CreateProjectionMatrix();
		}
	}
}